//888888888888888888888888888888888888888888888888888888888888888888888888888888888888888
//
//	File		 :	Sequence.h
//	Contents	 :	Header file for class CSequence
//	Creation Date:	22/12/1999
//	Last Modified:	07/01/20100	lg	// Y2K bug
//	tabs width	 :	every 4 characters
//
//888888888888888888888888888888888888888888888888888888888888888888888888888888888888888
#if !defined(SEQUENCE_H)
#define SEQUENCE_H

#include <vector>
#include <string>

#include "annotateoptions.h"

extern char C_NOTWHITESPACE[256];
inline int iswhitespace(char c) {return ~C_NOTWHITESPACE[c];}
inline char isnonwhitespace(char c) {return C_NOTWHITESPACE[c];}

struct CSequenceInvalid
{
	bool		Whitespace;
	bool		Nonprinting;
	std::string	InvalidRes;
	std::string	LowercaseRes;
	std::string	NonStdLinkers;
	std::string	Name;
	bool isInvalid() const { return Whitespace				||
									Nonprinting				||
									!InvalidRes.empty()		||
									!LowercaseRes.empty()	||
									!NonStdLinkers.empty();
							}
};

struct CSequence
{
	typedef std::string T_data;
	typedef std::vector<T_data> vec_data;
	typedef std::vector<T_data> vec_str;
	CSequence::CSequence(): FormatType(eUnknown){}
	enum eFormatType{eFASTA, eCLUSTAL, eMSF, ePHD, ePHDSAF, eDSC, eUnknown} FormatType;
	unsigned Len;
	vec_str		Names;
	vec_data	Data;
	vec_str		ExtraNames;
	vec_data	ExtraData;

	void	Clear();
	void	Remove(unsigned index);

	// accessors
	unsigned	Count() const { return Names.size();}
	unsigned	ExtraCount() const { return ExtraNames.size();}

	// excise
	void Excise(unsigned s, unsigned e);
	
	// removegaps
	void RemoveGaps(const char* loopupTable);
		
	// elision
	void	ElideSparseRegions(unsigned thresholdEmpty, unsigned minimumLen,
								bool allowLowerCase, const std::string& invalidStrings);

	// sequence name
	void	CreateConsensusName(bool useThreshold, unsigned threshold);

	// substitution
	void	ToUpper_and_Substitute(bool toupper, bool substitute, char to, const std::string& from);
	
	// Justify names
	void	JustifyNames(COptions::JUSTIFY_FLAG f);
	unsigned	GetNamesMaxLen() const;
	// validity checking
	bool	ChkValidity(std::vector<CSequenceInvalid>& invalidSequences,
						bool allowLowerCase, bool allowStrangeLinkers,
						const std::string& invalidResidues) const;
	bool	CheckLengthsEq() const;
	unsigned	CheckDuplicateNamesCnt() const;
	int		CheckEmptyData() const;
	void	RemoveEmptyData();

#ifndef NDEBUG
	bool IS_VALID() const;
#endif
};

inline void CSequence::Clear()
{
	Data.clear();
	Names.clear();
	Len = 0;
}
#endif // #define SEQUENCE_H
